package com.wanban.downloader.utils

import android.text.TextUtils
import android.util.Log
import com.blankj.utilcode.util.FileIOUtils
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.PathUtils
import com.blankj.utilcode.util.ThreadUtils
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.channels.FileChannel

object FileDownloadUtils {

    /**
     * 创建并返回下载的根目录
     * /Data/Android/xxx/files/Wanban
     */
    fun getOrCreateDownloadRootFileDirPath() : String? {
        val downloadRootDirPath = PathUtils.getFilesPathExternalFirst() + File.separator + "Wanban"
        val isCreateRootSuccess = FileUtils.createOrExistsDir(downloadRootDirPath)
        return if (isCreateRootSuccess) {
            downloadRootDirPath
        } else {
            null
        }
    }

    /**
     * 根据视频名称，创建当前视频下载的根目录
     * @param fileName
     *   /Data/Android/xxx/files/Wanban/${fileName}
     */
    fun getOrCreateVideoRootFileDirPath(fileName: String): String? {
        val root = getOrCreateDownloadRootFileDirPath()?:return null
        val videoFileDirPath = root + File.separator + fileName
        val createCoverSuccess = FileUtils.createOrExistsDir(videoFileDirPath)
        return if (createCoverSuccess)
            videoFileDirPath
        else
            null
    }

    /**
     * 创建并返回封面文件路径
     * @param fileName
     *   /Data/Android/xxx/files/Wanban/${fileName}/Cover/cover.png
     */
    fun getOrCreateCoverFilePath(fileName: String) : String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)?:return null
        val coverDirPath = root + File.separator + "Cover"
        val createCoverSuccess = FileUtils.createOrExistsDir(coverDirPath)
        if (!createCoverSuccess) return null
        val coverFilePath = coverDirPath + File.separator + "cover.png"
        val isCoverFilePath = FileUtils.createOrExistsFile(coverFilePath)
        return if (isCoverFilePath) {
            coverFilePath
        } else {
            null
        }
    }

    fun getCoverFilePath(fileName: String): String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)?:return null
        val coverDirPath = root + File.separator + "Cover"
        val createCoverSuccess = FileUtils.createOrExistsDir(coverDirPath)
        if (!createCoverSuccess) return null
        return coverDirPath + File.separator + "cover.png"
    }

    /**
     * 创建并返回M3U文件路径
     * @param fileName
     * /Data/Android/xxx/files/Wanban/${fileName}/M3U/local.m3u
     */
    fun geM3UFilePath(fileName: String): String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)?:return null
        // 创建文件夹
        val targetFileDirPath = root + File.separator + "M3U"
        val isCreateDir = FileUtils.createOrExistsDir(targetFileDirPath)
        if (!isCreateDir) {
            return null
        }
        return targetFileDirPath + File.separator + "local.m3u"
    }

    fun getM3U8KeyFileDirPath(fileName: String): String?{
        val root = getOrCreateVideoRootFileDirPath(fileName)
        if (TextUtils.isEmpty(root)) {
            return null
        }
        // 创建文件夹
        val targetFileDirPath = root + File.separator + "Keys"
        val isCreateDir = FileUtils.createOrExistsDir(targetFileDirPath)
        if (!isCreateDir) {
            return null
        }
        return targetFileDirPath
    }

    fun getOrCreateTsFileDirPath(fileName: String): String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)
        if (TextUtils.isEmpty(root)) {
            return null
        }
        // 创建文件夹
        val targetFileDirPath = root + File.separator + "TsList"
        val isCreateDir = FileUtils.createOrExistsDir(targetFileDirPath)
        if (!isCreateDir) {
            return null
        }
        return targetFileDirPath
    }

    fun getTsFilePath(fileDirPath: String?, tsFilePath: String): String{
        return fileDirPath + File.separator + tsFilePath
    }

    fun getOrCreateProxyM3U8File(fileName: String): String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)?:return null
        // 创建文件夹
        val targetFileDirPath = root + File.separator + "Proxy"
        val isCreateDir = FileUtils.createOrExistsDir(targetFileDirPath)
        if (!isCreateDir) {
            return null
        }
        val path = targetFileDirPath + File.separator + "proxy.m3u8"
        val isCreateFile = FileUtils.createOrExistsFile(path)
        if (!isCreateFile) {
            return null
        }
        return path
    }


    fun getMp4FilePath(fileName: String): String? {
        val root = getOrCreateVideoRootFileDirPath(fileName)?:return null
        // 创建文件夹
        val targetFileDirPath = root + File.separator + "Mp4"
        val isCreateDir = FileUtils.createOrExistsDir(targetFileDirPath)
        if (!isCreateDir) {
            return null
        }
        return targetFileDirPath + File.separator + "final.mp4"
    }





    /**
     * 下载单个文件
     */
    fun downloadFile(url: String?, filePath: String?, header: Map<String, String>? = null, complete: (isSuccess: Boolean, msg: String?) -> Unit){
        if (TextUtils.isEmpty(url) || TextUtils.isEmpty(filePath)) {
            complete(false, ErrorMessage.ERROR_URL_IS_NULL)
            return
        }
        // 创建文件
        val createCoverFileSuccess = FileUtils.createFileByDeleteOldFile(filePath)
        if (!createCoverFileSuccess) {
            complete(false, ErrorMessage.ERROR_FILE_CREATE_FAIL)
            return
        }
        val task = object: ThreadUtils.Task<Boolean>() {
            var connectUtils : HttpConnectUtils? = null
            override fun doInBackground(): Boolean {
                connectUtils = HttpConnectUtils()
                val inputStream = connectUtils?.open(url!!, header) ?: return false
                return FileIOUtils.writeFileFromIS(filePath, inputStream)
            }

            override fun onCancel() {
                connectUtils?.close()
                complete(false, ErrorMessage.ERROR_USER_CANCEL)
            }

            override fun onFail(t: Throwable?) {
                t?.printStackTrace()
                connectUtils?.close()
                complete(false, t?.message)
            }

            override fun onSuccess(result: Boolean?) {
                connectUtils?.close()
                complete(true, null)
            }
        }
        task.setTimeout(Constants.TIME_OUT) {
            complete(false, ErrorMessage.ERROR_DOWNLOAD_FILE_TIME_OUT)
        }
        // 下载
        ThreadUtils.executeByIo(task)
    }


}